<script setup>
import { onMounted, ref } from 'vue'
import { Peer } from 'peerjs'
const localVideo = ref(null)
const remoteVideo = ref(null)
let remoteStream = null
const peerId = ref('')
const message = ref('')
const messageList = ref([])
const peer = new Peer({
  host: '192.168.137.130',
  port: 9000,
  path: '/peerjs',
  config: {},
  secure: false
})
// const peer = new Peer()
peer.on('open', (id) => {
  peerId.value = id
  console.log('peer已成功连接' + id)
})
peer.on('error', (id) => {
  console.log('peer连接失败' + id)
})

/**
 * 监听 'icecandidate' 事件处理 ICE 候选项
 * 在同一设备上，webrtc内部不会触发icecandidate事件，因为不存在网络问题
 */
peer.on('icecandidate', function (iceCandidate) {
  console.log('ICE candidate:', iceCandidate)
})

/**
 * 监听connection事件处理数据通道连接
 */
let dataConnection = null
peer.on('connection', (connection) => {
  console.log('data数据通道连接-222')
  dataConnection = connection
  dataConnection.on('data', (data) => {
    sendMessage('remote', data)
  })
})

/**
 *监听 'icecandidate' 事件处理 ICE 候选项
 */
peer.on('icecandidate', function (iceCandidate) {
  console.log('ICE candidate:', iceCandidate)
})
let localStream = null
onMounted(async () => {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: { width: 200, height: 150 },
    audio: true
  })
  localStream = stream
  localVideo.value.srcObject = localStream
})
/**
 * 监听call事件
 * 通过call.answer回复，传递当前的视频流
 * 通过on监听到远端传递的视频流然后显示
 */
let callObj = ref(null)
peer.on('call', (call) => {
  console.log('监听到视频呼叫')
  callObj.value = call
})
/**
 * 手动接收call的呼叫，进行答复
 */
const receiveCall = () => {
  callObj.value.answer(localStream)
  callObj.value.on('stream', (stream) => {
    remoteStream = stream
    remoteVideo.value.srcObject = remoteStream
  })
  callObj.value.on('close', () => {
    console.log('视频流关闭了')
    remoteStream = null
  })
}
/**
 * 发送消息
 * @param { string } type 消息类型 self和remote
 * @param { string } data 消息数据
 */
const sendMessage = (type, data) => {
  messageList.value.push({
    message: type === 'self' ? message.value : data,
    type,
    time: new Date().getTime()
  })
  if (type === 'self') {
    dataConnection.send(message.value)
    message.value = ''
  }
}
/**
 * 主动断开连接
 */
const closeCall = () => {
  callObj.value.close()
}
</script>

<template>
  <div class="chat-page">
    <div class="header">
      <div>ID: {{ peerId }}</div>
      <el-button v-if="callObj" @click="receiveCall" type="primary">接收视频</el-button>
      <el-button v-if="remoteStream" @click="closeCall" type="danger">断开连接</el-button>
    </div>
    <div class="content">
      <div class="left">
        <video ref="localVideo" class="video-preview" autoplay></video>
        <div class="user-name">自己</div>
        <video ref="remoteVideo" class="video-preview" autoplay></video>
        <div class="user-name">远端</div>
      </div>
      <div class="center">
        <div class="message-list">
          <ul>
            <li
              :style="{ textAlign: item.type === 'self' ? 'right' : 'left' }"
              v-for="(item, index) in messageList"
              :key="index"
            >
              <span>{{ item.type === 'self' ? '自己' : '远端' }}：</span>
              {{ item.message }}
            </li>
          </ul>
        </div>
        <div class="chat-input">
          <el-input
            v-model="message"
            placeholder="请输入内容"
            @keyup.enter="sendMessage('self')"
          ></el-input>
          <el-button type="primary" :disabled="!message" @click="sendMessage('self')"
            >发送</el-button
          >
        </div>
      </div>
      <div class="right"></div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.chat-page {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  .header {
    height: 40px;
    line-height: 40px;
    background-color: #444;
    padding: 0 5px;
    color: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .content {
    flex: 1;
    display: flex;
  }
  .left {
    width: 200px;
  }
  .center {
    flex: 1;
    display: flex;
    flex-direction: column;
    background-color: #eee;
    .message-list {
      flex: 1;
      height: 0;
      overflow-y: auto;
      li {
        padding: 5px;
      }
    }
    .chat-input {
      padding: 5px;
      display: flex;
      align-items: center;
    }
  }

  .video-preview {
    width: 200px;
    height: 150px;
    object-fit: contain;
    display: block;
  }
  .user-name {
    height: 20px;
    line-height: 20px;
    font-size: 12px;
    text-align: center;
    background-color: #ccc;
  }
}
</style>
